package org.csu.mybigpro.util;

import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import io.minio.GetObjectArgs; // 导入 GetObjectArgs
import io.minio.errors.MinioException; // 导入 MinioException
import lombok.extern.slf4j.Slf4j;
import org.csu.mybigpro.properties.MinioProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream; // 导入 InputStream
import java.io.IOException; // 导入 IOException
import java.security.InvalidKeyException; // 导入 InvalidKeyException
import java.security.NoSuchAlgorithmException; // 导入 NoSuchAlgorithmException
import java.util.UUID;
import java.net.URL; // 导入 URL 类

@Component
@Slf4j
public class MinioUtil {

    @Autowired
    private MinioProperties minioProperties;

    @Autowired
    private MinioClient minioClient;

    /**
     * 上传文件
     * @param file 要上传的 MultipartFile
     * @return 文件的 Minio 访问 URL
     * @throws Exception 上传过程中可能抛出的异常
     */
    public String uploadFile(MultipartFile file) throws Exception {
        if (file == null || file.getSize() == 0) {
            log.error("==> 上传文件异常：文件大小为空 ...");
            throw new RuntimeException("文件大小不能为空");
        }

        String originalFileName = file.getOriginalFilename();
        String contentType = file.getContentType();

        String key = UUID.randomUUID().toString().replace("-", "");
        String suffix = originalFileName.substring(originalFileName.lastIndexOf("."));
        String objectName = String.format("%s%s", key, suffix);

        log.info("==> 开始上传文件至 Minio, ObjectName: {}", objectName);

        minioClient.putObject(PutObjectArgs.builder()
                .bucket(minioProperties.getBucketName())
                .object(objectName)
                .stream(file.getInputStream(), file.getSize(), -1)
                .contentType(contentType)
                .build());

        String url = String.format("%s/%s/%s", minioProperties.getEndpoint(), minioProperties.getBucketName(), objectName);
        log.info("==> 上传文件至 Minio 成功，访问路径: {}", url);
        return url;
    }

    /**
     * 从 Minio 下载文件并返回其输入流
     * @param bucketName 存储桶名称
     * @param objectName 对象名称 (文件在 Minio 中的完整路径)
     * @return 文件的 InputStream
     * @throws IOException
     * @throws InvalidKeyException
     * @throws NoSuchAlgorithmException
     * @throws MinioException
     */
    public InputStream downloadFile(String bucketName, String objectName)
            throws IOException, InvalidKeyException, NoSuchAlgorithmException, MinioException {
        log.info("==> 从 Minio 下载文件, Bucket: {}, Object: {}", bucketName, objectName);
        return minioClient.getObject(
                GetObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .build());
    }

    /**
     * 删除 Minio 中的文件
     * @param bucketName 存储桶名称
     * @param objectName 对象名称 (文件在 Minio 中的完整路径)
     * @throws Exception 删除过程中可能抛出的异常
     */
    public void deleteFile(String bucketName, String objectName) throws Exception {
        log.info("==> 开始从 Minio 删除文件, Bucket: {}, Object: {}", bucketName, objectName);
        minioClient.removeObject(
                RemoveObjectArgs.builder()
                        .bucket(bucketName)
                        .object(objectName)
                        .build());
        log.info("==> 从 Minio 删除文件成功, Object: {}", objectName);
    }

    /**
     * 从 Minio URL 中解析出存储桶名称
     * @param minioUrl Minio 文件的完整 URL
     * @return 存储桶名称，如果解析失败返回 null
     */
    public String getBucketNameFromUrl(String minioUrl) {
        try {
            URL url = new URL(minioUrl);
            String path = url.getPath();
            if (path.startsWith("/")) {
                path = path.substring(1);
            }
            int firstSlashIndex = path.indexOf('/');
            if (firstSlashIndex != -1) {
                return path.substring(0, firstSlashIndex);
            }
        } catch (Exception e) {
            log.error("解析 Minio URL 存储桶失败: {}", minioUrl, e);
        }
        return null;
    }

    /**
     * 从 Minio URL 中解析出对象名称
     * @param minioUrl Minio 文件的完整 URL
     * @return 对象名称，如果解析失败返回 null
     */
    public String getObjectNameFromUrl(String minioUrl) {
        try {
            URL url = new URL(minioUrl);
            String path = url.getPath();
            if (path.startsWith("/")) {
                path = path.substring(1);
            }
            int firstSlashIndex = path.indexOf('/');
            if (firstSlashIndex != -1) {
                return path.substring(firstSlashIndex + 1);
            }
        } catch (Exception e) {
            log.error("解析 Minio URL 对象名称失败: {}", minioUrl, e);
        }
        return null;
    }
}